package com.aaa.methodreference.demo06;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.junit.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.stream.Stream;

/**
 * @author C-Q
 * @version 1.1.0
 *
 * @Description: Stream流
     * Java8中的两个重大改变，一个是Lambda表达式，另一个就是本节要讲的StreamAPI表达式；
     * Stream是Java8中处理集合的关键抽象概念，它可以对集合进行非常复杂的查找、过滤、筛选等操作；
 *
 * @date 2022/11/4
 */
public class StreamTest {
    /*使用集合遍历来体验集合操作数据的弊端*/
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list,"李易峰","吴凡","张家辉","彭于晏");

        //1.获取所有姓张的
        ArrayList<String> list1 = new ArrayList<>();
        for (String s : list) {
            if(s.startsWith("张")){
                list1.add(s);
            }
        }
        //2.名字中含有三个子
        ArrayList<String> list2 = new ArrayList<>();
        for (String s : list) {
            if(s.length()==3){
                list2.add(s);
                //System.out.println("s = " + s);
            }
        }
        //3.打印
        for (String n : list2) {
            System.out.println("n = " + n);
        }
        /*每当我们需要对集合中的元素进行操作的时候，
        总是需要进行循环、循环、再循环。这是理所当然的么？
        不是。循环 是做事情的方式，而不是目的。每个需求都要循环一次，
        还要搞一个新集合来装数据，如果希望再次遍历，只能再使用另一个循环从头开始。*/
    }
    @Test
    public void Test1(){
        //使用Stream流来体验上面对集合的操作
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list,"李易峰","吴凡","张家辉","彭于晏");

        //Consumer<String> consumer=item-> System.out.println(item);
        list.stream()
                .filter(item->item.startsWith("张"))
                .filter(item->item.length()==3)
                //.forEach(item-> System.out.println(item));
                .forEach(System.out::println);
    }
    @Test
    public void Test2(){
        /*获取Stream流对象
        获取流对象的方式有三种:
        1.通过集合名获取
        2.通过Arrays中的静态方法获取Stream
        3.通过Stream中的静态方法of */
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list,"成龙","王宝强","洪金宝","甑子丹","李连杰");

        //通过集合对象调用stream方法获取
        Stream<String> stream=list.stream();

        //通过arrays数组工具类调用stream方法
        String[] arr={"张三","周六","李四","王五"};
        Stream<String> stream1= Arrays.stream(arr);

        //通过stream类中的方法获取stream流对象
        Stream<String> stream2=Stream.of("张三","李四");

        /*拿到流对象后才能操作Stream类中的相关的方法*/

    }
    @Test
    public void Test3() {
        //假设有个Person类和一个Person列表，现在有两个需求:
        //1.找到年龄大于18岁的人并输出；
        //2.找出所有中国人的数量
        ArrayList<Person> people = new ArrayList<>();
        people.add(new Person("上官雪", 18, "中国", 'A'));
        people.add(new Person("慕容复", 14, "法国", 'B'));
        people.add(new Person("逍遥散", 57, "伊拉克", 'B'));
        people.add(new Person("宇文都", 36, "比利时", 'B'));
        people.add(new Person("易烊玺", 45, "中国", 'A'));
        people.add(new Person("无为治", 15, "荷兰", 'A'));

        //1.找到年龄大于18岁的人并输出
        //filter 它就是中间操作的方法，如果没有执行终止操作方法那么中间操作都不会执行，执行了终止操作方法时才会执行中间操作的方法
        people.stream()
                .filter(item->{return item.getAge()>18;})
                .forEach(System.out::println);
                //forEach属于终止操作方法
        //2.找出所有中国人的数量
        long count = people.stream().filter(item -> item.getCountry().equals("中国")).count();
        System.out.println("count = " + count);
    }
    /*中间操作就是filter
    forEach和count都属于终止操作方法*/
}

@Data
@NoArgsConstructor
@AllArgsConstructor
class Person{
    private String name;
    private Integer age;
    private String country;
    private char sex;
}
